package com.ophiux.utils.common;

import java.math.BigDecimal;
import java.text.NumberFormat;

/**
 * 数字转化工具类@desc：<br>
 * 
 * @author: hhl<br>
 * @date: 2021年9月3日 上午9:42:07<br>
 */
public class NumberUtil {

	/**
	 * Description:获取2个数字的比例，含四舍五入0.0000 <br>
	 * 创 建 人: hhl 创建日期:2018年5月24日 下午2:34:03
	 * 
	 * @param a 被除数
	 * @param b 除数
	 * @return
	 */
	public static String getRate(String a, String b) {
		if (StringUtil.isEmpty(a)) {
			a = "0";
		}
		return divide(Double.parseDouble(a), Double.parseDouble(b), 4) + "";
	}

	/**
	 * Description: 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指 定精度，以后的数字四舍五入。 <br>
	 * 创 建 人: hhl 
	 * 创建日期:2018年6月9日 下午2:25:35
	 * 
	 * @param v1    被除数
	 * @param v2    除数
	 * @param scale 表示表示需要精确到小数点以后几位。
	 * @return
	 */
	public static double divide(double v1, double v2, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		double c = b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
		// 保留4位小数
		return round(c, scale);
	}

	/**
	 * Description:计算2个字符串数字之和 <br>
	 * 创 建 人: hhl 创建日期:2018年5月24日 下午2:52:25
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public static String sum(String a, String b) {
		if (StringUtil.isEmpty(a)) {
			a = "0";
		}
		if (StringUtil.isEmpty(b)) {
			b = "0";
		}
		BigDecimal a1 = new BigDecimal(a);
		BigDecimal b1 = new BigDecimal(b);

		// 2018-08-02 陈辉将doubleValue改为toPlainString，以防出现科学计数
		// String c = a1.add(b1).doubleValue()+"";
		String c = a1.add(b1).toPlainString();
		return c;
	}

	/**
	 * Description:比较2个字符串数字的大小 <br>
	 * 创 建 人: hhl 创建日期:2018年5月24日 下午2:48:50
	 * 
	 * @param a 前者
	 * @param b 后者
	 * @return
	 */
	public static Boolean compareSize(String a, String b) {
		if (StringUtil.isEmpty(a)) {
			a = "0";
		}
		if (StringUtil.isEmpty(b)) {
			b = "0";
		}
		if (Double.parseDouble(a) > Double.parseDouble(b)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Description:计算2个数之差 <br>
	 * 创 建 人: hhl 创建日期:2018年5月30日 下午9:14:18
	 * 
	 * @param a 被减数
	 * @param b 减数
	 * @return
	 */
	public static String difference(String a, String b) {
		if (StringUtil.isEmpty(a)) {
			a = "0";
		}
		if (StringUtil.isEmpty(b)) {
			b = "0";
		}
		BigDecimal a1 = new BigDecimal(a);
		BigDecimal b1 = new BigDecimal(b);
		return a1.subtract(b1).doubleValue() + "";
	}

	/**
	 * Description:计算2个数之差，提供精确的小数位四舍五入处理。 <br>
	 * 创 建 人: hhl 创建日期:2018年5月30日 下午9:14:18
	 * 
	 * @param v     需要四舍五入的数字
	 * @param scale 小数点后保留几位
	 * @return 四舍五入后的结果
	 */
	public static double round(double v, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b = new BigDecimal(Double.toString(v));
		BigDecimal one = new BigDecimal("1");
		return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 提供精确的乘法运算。
	 * 
	 * @param v1 被乘数
	 * @param v2 乘数
	 * @return 两个参数的积
	 */
	public static double multiply(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.multiply(b2).doubleValue();
	}

	/**
	 * 验证字符串是否为数字，含小数
	 * 
	 * @param value  数据源
	 * @param digits 限制的位数，小数点超过位数，返回验证不通过 true:通过 false:不通过
	 * @return
	 */
	public static boolean isNumberic(String value, int digits) {

		boolean flag = true;
		try {
			if (StringUtil.isEmpty(value)) {
				return false;
			}
			String numberic = "0123456789"; // 数字集
			// 是否已存在小数点
			boolean haspoint = false;

			// 循环判断每个字节
			for (int i = 0; i < value.length(); i++) {
				char temp = value.charAt(i);

				// 大于1位的，第一位，可以是 +、-
				if (i == 0 && value.length() > 1) {
					if (String.valueOf(temp).equals("+") || String.valueOf(temp).equals("-")) {
						continue;
					}
				}

				// 验证小数点
				if (String.valueOf(temp).equals(".")) {
					if (haspoint) {
						// 已经出现过小数点，则不能再出现小数点
						return false;
					}
					haspoint = true;
				} else {
					// 验证数字
					if (!numberic.contains(String.valueOf(temp))) {
						return false;
					}
				}
			} // 基本验证完毕

			// 按小数点拆分
			String arr[] = value.split("\\.");

			// 验证小数位数
			if (digits != -1) {
				if (arr.length != 2) {
					return false;
				}
				// 取得小数点后面的字符串
				String afterPoint = arr[1];
				if (afterPoint.length() != digits) {
					// 小数位数和指定位数不匹配
					return false;
				}
			}

			// 验证整数部分，数字开始位不能是 0
			String frontPoint = arr[0];
			// 获取第一项
			int index = 0;// 数字首位下标
			String first = frontPoint.substring(0, 1);
			if (first.equals("+") || first.equals("-")) {
				// 第一项是 +或-，则继续取第二项
				first = frontPoint.substring(1, 2);
				index = 1;
			}
			// 验证整数部分，数字开始位不能是 0
			if (!first.equals("0")) {
				return true;
			}
			// 等于0时，还得判断0后面是否还有非0数，有则不通过，如：012.23
			for (int i = index; i < frontPoint.length(); i++) {
				if (!String.valueOf(frontPoint.charAt(i)).equals("0")) {
					return false;
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return flag;
	}

	/**
	 * 验证字符串是否为数字，含小数
	 * 
	 * @param value  数据源
	 * @param digits 限制的位数，小数点超过位数，返回验证不通过 true:通过 false:不通过
	 * @return
	 */
	public static boolean isNumberic(String value) {

		return isNumberic(value, -1);
	}

	public static void main(String[] args) {
		/*
		 * String value = "-324322.01265"; boolean flag = false; try { flag =
		 * isNumberic(value, -1); } catch (Exception e) { e.printStackTrace(); }
		 * System.out.println(flag);
		 */
//		float point = 0.5674f;
//		String percent = point2Percent(point);
//		System.out.println(percent);
		String r = "4896156156415645";
		BigDecimal b1 = new BigDecimal(r);
		System.out.println(b1.toPlainString());
		System.out.println(b1.doubleValue());
		// System.out.println(isZero("-0.00"));
	}

	/**
	 * 保留几位小数
	 * 
	 * @param a     分子
	 * @param b     分母
	 * @param scale 保留小数位数
	 * @return
	 */
	public static String getRate(String a, String b, int scale) {
		if (StringUtil.isEmpty(a)) {
			a = "0";
		}
		return divide(Double.parseDouble(a), Double.parseDouble(b), scale) + "";
	}

	/**
	 * 小数点转为百分号
	 * 
	 * @param point
	 * @return
	 */
	public static String point2Percent(float point) {
		String percent = "";
		try {
			NumberFormat nf = NumberFormat.getPercentInstance();
			// 这个1的意识是保存结果到小数点后几位，但是特别声明：这个结果已经先＊100了。
			nf.setMaximumFractionDigits(2);
			percent = nf.format(point);
			System.out.println(percent);// 自动四舍五入。
		} catch (Exception e) {
			e.printStackTrace();
		}
		return percent;
	}

	/**
	 * 判断字符串是否全是数字
	 * 
	 * @param str true：是 false:不是
	 * @return
	 */
	public static boolean isDigitString(String value) {
		boolean flag = true;
		if (StringUtil.isEmpty(value))
			return false;
		String numberic = "0123456789"; // 数字集
		try {

			for (int i = 0; i < value.length(); i++) {
				char temp = value.charAt(i);
				if (!numberic.contains(String.valueOf(temp))) {
					return false;
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 判断某数字是否等于0 true:等于 false：不等于
	 * 
	 * @param number
	 * @return
	 */
	public static boolean isZero(float number) {
		BigDecimal bd = new BigDecimal("0");
		BigDecimal b_number = new BigDecimal(number + "");
		int res = b_number.compareTo(bd);

		return res == 0 ? true : false;

	}

	/**
	 * 判断某数字是否等于0 true:等于 false：不等于
	 * 
	 * @param number
	 * @return
	 */
	public static boolean isZero(BigDecimal number) {
		BigDecimal bd = new BigDecimal("0");
		int res = number.compareTo(bd);

		return res == 0 ? true : false;

	}

	/**
	 * Description: 判断某数字是否大于0<br>
	 * 创 建 人: hhl 创建日期:2018年7月23日 下午2:12:02
	 * 
	 * @param number
	 * @return
	 */
	public static boolean isZero(String number) {
		BigDecimal b_number = new BigDecimal(number + "");
		int i = b_number.compareTo(BigDecimal.ZERO);
		if (i == -1) {
			return false;
		} else if (i == 0) {
			return false;
		} else if (i == 1) {
			return true;
		} else {
			return false;
		}

	}

	/**
	 * 判断某数字是否等于0 2018-08-02 陈辉新增 true:等于 false：不等于
	 * 
	 * @param number
	 * @return
	 */
	public static boolean isZero_New(String number) {
		BigDecimal bd = new BigDecimal("0");
		BigDecimal b_number = new BigDecimal(number);

		int res = b_number.compareTo(bd);

		return res == 0 ? true : false;

	}

}
